/*
 * prefutils.js v1.0 Wrapper for Mozilla preferences XPCOM components. Copyright
 * (c) 2005 Nickolay Ponomarev <asqueella@gmail.com>
 * 
 * WARNING: This code is not enough tested yet (not final).
 * 
 * You may use this code in any way you want, but please send your changes back
 * to me if you think they may be useful to anybody else. Also please change the
 * object's name if you change the code before using it in an extension.
 * 
 * Also if you decide to use it intact in your code, please drop me a line.
 * 
 * Quick Examples: var gMyPrefs = new PrefsWrapper("extensions.myextension.");
 * var lastname = gMyPrefs.getUnicharPref("user.lastname"); // or call any
 * nsIPrefBranch method: var age = gMyPrefs.getIntPref("user.age"); // or a
 * nsPreferences-like variant (with built-in exception handling): var middlename =
 * gMyPrefs.getUnicharPrefDef("user.middlename", "default"); // get wrapper for
 * a sub-branch with: var branch = gMyPrefs.getSubBranch("user.");
 * 
 * Documentation is available at http://mozilla.doslash.org/prefutils
 */

// do not define the same version twice
if (typeof(PrefsWrapper) != "function") {
	function PrefsWrapper(aRoot) {
		const CI = Components.interfaces;
		this.prefSvc = Components.classes["@mozilla.org/preferences-service;1"]
				.getService(CI.nsIPrefService);
		this.prefSvc.QueryInterface(CI.nsIPrefBranch);
		this.branch = this.prefSvc.getBranch(aRoot);

		this.prefSvc.QueryInterface(CI.nsIPrefBranchInternal);
		this.branch.QueryInterface(CI.nsIPrefBranchInternal);

		// "inherit" from nsIPrefBranch, re-assembling __proto__ chain as
		// follows:
		// this, nsIPrefBranch, PrefsWrapper.prototype, Object.prototype
		this.branch.__proto__ = PrefsWrapper.prototype;
		this.__proto__ = this.branch;

	}

	PrefsWrapper.prototype = {
		getIntPrefDef : function(aPrefName, aDefValue) {
			try {
				return this.getIntPref(aPrefName);
			} catch (e) {
				return aDefValue;
			}
		},
		getCharPrefDef : function(aPrefName, aDefValue) {
			try {
				return this.getCharPref(aPrefName);
			} catch (e) {
				return aDefValue;
			}
		},
		getBoolPrefDef : function(aPrefName, aDefValue) {
			try {
				return this.getBoolPref(aPrefName);
			} catch (e) {
				return aDefValue;
			}
		},
		getUnicharPrefDef : function(aPrefName, aDefValue) {
			try {
				return this.getUnicharPref(aPrefName);
			} catch (e) {
				return aDefValue;
			}
		},
		getFilePrefDef : function(aPrefName, aDefValue) {
			try {
				return this.getFilePref(aPrefName);
			} catch (e) {
				return aDefValue;
			}
		},
		getSubBranch : function(aSubpath) {
			return new PrefsWrapper(this.branch.root + aSubpath);
		},

		// unicode strings
		getUnicharPref : function(aPrefName) {
			return this.branch.getComplexValue(aPrefName,
					Components.interfaces.nsISupportsString).data;
		},
		setUnicharPref : function(aPrefName, aValue) {
			var str = Components.classes["@mozilla.org/supports-string;1"]
					.createInstance(Components.interfaces.nsISupportsString);
			str.data = aValue;
			this.branch.setComplexValue(aPrefName,
					Components.interfaces.nsISupportsString, str);
		},

		// for strings with default value stored in locale's .properties file
		getLocalizedUnicharPref : function(aPrefName) {
			return this.branch.getComplexValue(aPrefName,
					Components.interfaces.nsIPrefLocalizedString).data;
		},

		// store nsILocalFile in prefs
		setFilePref : function(aPrefName, aValue) {
			this.branch.setComplexValue(aPrefName,
					Components.interfaces.nsILocalFile, aValue);
		},
		getFilePref : function(aPrefName) {
			return this.branch.getComplexValue(aPrefName,
					Components.interfaces.nsILocalFile);
		},

		// aRelTo - relative to what directory (f.e. "ProfD")
		setRelFilePref : function(aPrefName, aValue, aRelTo) {
			var relFile = Components.classes["@mozilla.org/pref-relativefile;1"]
					.createInstance(Components.interfaces.nsIRelativeFilePref);
			relFile.relativeToKey = aRelTo;
			relFile.file = aValue;
			this.branch.setComplexValue(aPrefName,
					Components.interfaces.nsIRelativeFilePref, relFile);
		},
		getRelFilePref : function(aPrefName) {
			return this.branch.getComplexValue(aPrefName,
					Components.interfaces.nsIRelativeFilePref).file;
		},

		// don't throw an exception if the pref doesn't have a user value
		clearUserPrefSafe : function(aPrefName) {
			try {
				this.branch.clearUserPref(aPrefName);
			} catch (e) {
			}
		}
	}
}
